﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ComputerGraphics.Geometry;

namespace ComputerGraphics.Graphics
{
    public class Camera
    {
        private Point3D viewPoint;

        private Point3D front;
        private Point3D right;
        private Point3D up;
        private double fovScale;

        public Camera(Point3D viewPoint, Point3D viewPlaneCenter, Point3D refUp, double fov)
        {
            this.front = viewPlaneCenter - viewPoint;
            double focusLen = front.Norm;

            this.viewPoint = viewPoint;
            this.fovScale = focusLen * Math.Tan(fov * 0.5 * Math.PI / 180) * 2;

            this.right = (front ^ refUp).Direction;
            this.up = (right ^ front).Direction;
        }

        public Ray GetRay(double x, double y)
        {
            Point3D r = right * ((x - 0.5) * fovScale);
            Point3D u = up * ((y - 0.5) * fovScale);

            return new Ray(viewPoint, (front + u + r).Direction);
        }

        public Point3D ViewPoint
        {
            get { return viewPoint; }
        }

        public Point3D Front
        {
            get { return front; }
        }

        public Point3D Right
        {
            get { return right; }
        }

        public Point3D Up
        {
            get { return up; }
        }

        public Point3D ViewPlaneCenter
        {
            get { return viewPoint + front; }
        }
    }
}
